// dotnet $DOTNET_CSC_DLL -nologo -t:library  -r:"../../The Scroll of Taiwu_Data/Managed/netstandard.dll" -r:"../../The Scroll of Taiwu_Data/Managed/0Harmony.dll" -r:"../../The Scroll of Taiwu_Data/Managed/mscorlib.dll" -r:"../../The Scroll of Taiwu_Data/Managed/Assembly-CSharp.dll" -r:"../../The Scroll of Taiwu_Data/Managed/TaiwuModdingLib.dll" -r:"../../The Scroll of Taiwu_Data/Managed/Unity.TextMeshPro.dll" -r:"../../The Scroll of Taiwu_Data/Managed/UnityEngine.CoreModule.dll" -r:"../../The Scroll of Taiwu_Data/Managed/UnityEngine.UI.dll" -r:"../../The Scroll of Taiwu_Data/Managed/UnityEngine.dll" -optimize -deterministic NativeCommunicationsFrontend.cs *.CS -out:NativeCommunicationsFrontend.dll
// -r:"../../The Scroll of Taiwu_Data/Managed/Mono.Cecil.dll" -r:"../../The Scroll of Taiwu_Data/Managed/System.Core.dll"   -r:"../../The Scroll of Taiwu_Data/Managed/System.Composition.AttributedModel.dll"
/**
 *  Neutron's Taiwu Collections
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using HarmonyLib;
using Utils;

namespace FrontEndCommunications;
[TaiwuModdingLib.Core.Plugin.PluginConfig("FrontEndCommunications","Neutron3529","0.1.0")]
public class ASmallCollectionsFromNeutron : TaiwuModdingLib.Core.Plugin.TaiwuRemakePlugin {
    public override void Initialize(){
        this.HarmonyInstance = new RobustHarmonyInstance(this.GetGuid());
        this.HarmonyInstance.PatchAll(typeof(HandleDisplayEventsPatcher));
    }
    public override void Dispose()=>this.HarmonyInstance.UnpatchSelf();
    public static void logger(string s)=>GameData.Utilities.AdaptableLog.Info(s);
    public static void logwarn(string s)=>GameData.Utilities.AdaptableLog.Warning("<color=#FFFF00>"+s+"</color>",true);
    public RobustHarmonyInstance HarmonyInstance;

    [HarmonyPatch(typeof(DisplayEventHandler),"HandleDisplayEvents")]
    public class HandleDisplayEventsPatcher {
        public static MethodInfo HandleDisplayEvents=typeof(DisplayEventHandler).GetMethod("HandleDisplayEvents",(BindingFlags)(-1));
        public static Type[] args=new Type[]{typeof(GameData.Utilities.RawDataPool), typeof(int)};
        static bool block=true;
        static List<GameData.GameDataBridge.NotificationWrapper> lst=new List<GameData.GameDataBridge.NotificationWrapper>(){default(GameData.GameDataBridge.NotificationWrapper)};
        public static bool Prefix(List<GameData.GameDataBridge.NotificationWrapper> notifications){ // notifications非空
            if(block){
                block=false;
                object[] handleArg=new object[]{lst};
                foreach(var wrapper in notifications){
                    var notification=wrapper.Notification;
                    if(notification.DisplayEventType==65535){
                        int argsOffset = notification.ValueOffset;
                        GameData.Domains.Mod.ModId modId = default(GameData.Domains.Mod.ModId);
                        string methodName=null;
                        argsOffset += GameData.Serializer.Serializer.Deserialize(wrapper.DataPool, argsOffset, ref modId);
                        argsOffset += GameData.Serializer.Serializer.Deserialize(wrapper.DataPool, argsOffset, ref methodName);

                        List<TaiwuModdingLib.Core.Plugin.TaiwuRemakePlugin> plugins;
                        TaiwuModdingLib.Core.Plugin.TaiwuRemakePlugin plugin=null;
                        MethodInfo method=null;
                        if(((Dictionary<GameData.Domains.Mod.ModId,List<TaiwuModdingLib.Core.Plugin.TaiwuRemakePlugin>>)(typeof(ModManager).GetField("_loadedPlugins",(BindingFlags)(-1)).GetValue(null))).TryGetValue(modId,out plugins)) {
                            foreach(var plug in plugins){
                                method=plug.GetType().GetMethod(methodName, args);
                                if(method!=null){
                                    plugin=plug;
                                    break;
                                }
                            }
                        } else {
                            logwarn("[Mod Communication]: 无法在<color=#FF0000>前端</color>找到modId为("+modId.FileId+","+modId.Version+","+modId.Source+")的Mod，请检查ModId是否发生了更改。");
                            return false;
                        }

                        if(plugin==null){
                            logwarn("[Mod Communication]: 无法在<color=#FF0000>前端</color>modId为("+modId.FileId+","+modId.Version+","+modId.Source+")的Mod中找到函数public void "+methodName+"(GameData.Utilities.RawDataPool dataPool, int offset), 请确保Mod已正确加载");
                        } else {
                            method.Invoke(plugin, new object[]{wrapper.DataPool, argsOffset});
                        }
                    } else {
                        lst[0]=wrapper;
                        HandleDisplayEvents.Invoke(null,handleArg);
                    }
                }
                block=true;
                return false;
            } else {
                return true;
            }
        }
    }
}
